/**
  ******************************************************************************
  * @file    tc32l010_hal_crc.c
  * @author  CHIPAT Application Team
  * @brief   This file provides firmware functions to manage the following
  *          functionalities of CRC check:
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "tc32l010_crc.h"



/**
  * @brief  Computes the 16-bit CRC of 8-bit data buffer using combination
  *         of the previous CRC value and the new one.
  * @param  CRCx: pointer to a CRC_TypeDef structure that contains
  *         the configuration information for CRC
  * @param  pBuff: pointer to the buffer containing the data to be computed
  * @param  u32Len: length of the buffer to be computed (defined in word, 4 bytes)
  * @retval 16-bit CRC FLAG
  */
uint8_t CRC_Accumulate_8b(CRC_TypeDef* CRCx, uint8_t* pBuff, uint32_t u32Len)
{
    uint32_t index;

    CRCx->RESULT.RESULT = CRC_RESULT_RESULT;

    /* Enter Data to the CRC calculator */
    for(index = 0; index < u32Len; index ++)
    {
        *(volatile uint8_t*)(&CRCx->DATA) = pBuff[index];
    }

    /* Return the CRC computed value */
    return CRCx->RESULT.FLAG;
}

/**
  * @brief  Computes the 16-bit CRC of 8-bit data buffer independently
  *         of the previous CRC value.
  * @param  CRCx: pointer to a CRC_TypeDef structure that contains
  *         the configuration information for CRC
  * @param  pBuff: Pointer to the buffer containing the data to be computed
  * @param  u32Len: Length of the buffer to be computed (defined in word, 4 bytes)
  * @retval 16-bit CRC
  */
uint16_t CRC_Calculate_8b(CRC_TypeDef* CRCx, uint8_t* pBuff, uint32_t u32Len)
{
    uint32_t index;

    CRCx->RESULT.RESULT = CRC_RESULT_RESULT;

    /* Enter Data to the CRC calculator */
    for(index = 0; index < u32Len; index++)
    {
        *(volatile uint8_t*)(&CRCx->DATA) = pBuff[index];
    }

    /* Return the CRC computed value */
    return CRCx->RESULT.RESULT;
}

/**
  * @brief  Computes the 16-bit CRC of 8-bit data buffer using combination
  *         of the previous CRC value and the new one.
  * @param  CRCx: pointer to a CRC_TypeDef structure that contains
  *         the configuration information for CRC
  * @param  pBuff: pointer to the buffer containing the data to be computed
  * @param  u32Len: length of the buffer to be computed (defined in word, 4 bytes)
  * @retval 16-bit CRC FLAG
  */
uint8_t CRC_Accumulate_16b(CRC_TypeDef* CRCx, uint16_t* pBuff, uint32_t u32Len)
{
    uint32_t index;

    CRCx->RESULT.RESULT = CRC_RESULT_RESULT;

    /* Enter Data to the CRC calculator */
    for(index = 0; index < u32Len; index ++)
    {
        *(volatile uint16_t*)(&CRCx->DATA) = pBuff[index];
    }

    /* Return the CRC computed value */
    return CRCx->RESULT.FLAG;
}

/**
  * @brief  Computes the 16-bit CRC of 8-bit data buffer independently
  *         of the previous CRC value.
  * @param  CRCx: pointer to a CRC_TypeDef structure that contains
  *         the configuration information for CRC
  * @param  pBuff: Pointer to the buffer containing the data to be computed
  * @param  u32Len: Length of the buffer to be computed (defined in word, 4 bytes)
  * @retval 16-bit CRC
  */
uint16_t CRC_Calculate_16b(CRC_TypeDef* CRCx, uint16_t* pBuff, uint32_t u32Len)
{
    uint32_t index;
    
    CRCx->RESULT.RESULT = CRC_RESULT_RESULT;

    /* Enter Data to the CRC calculator */
    for(index = 0; index < u32Len; index++)
    {
        *(volatile uint16_t*)(&CRCx->DATA) = pBuff[index];
    }

    /* Return the CRC computed value */
    return CRCx->RESULT.RESULT;
}

/**
  * @brief  Computes the 16-bit CRC of 8-bit data buffer using combination
  *         of the previous CRC value and the new one.
  * @param  CRCx: pointer to a CRC_TypeDef structure that contains
  *         the configuration information for CRC
  * @param  pBuff: pointer to the buffer containing the data to be computed
  * @param  u32Len: length of the buffer to be computed (defined in word, 4 bytes)
  * @retval 16-bit CRC FLAG
  */
uint8_t CRC_Accumulate_32b(CRC_TypeDef* CRCx, uint32_t* pBuff, uint32_t u32Len)
{
    uint32_t index;

    CRCx->RESULT.RESULT = CRC_RESULT_RESULT;

    /* Enter Data to the CRC calculator */
    for(index = 0; index < u32Len; index ++)
    {
        *(volatile uint32_t*)(&CRCx->DATA) = pBuff[index];
    }

    /* Return the CRC computed value */
    return CRCx->RESULT.FLAG;
}

/**
  * @brief  Computes the 16-bit CRC of 8-bit data buffer independently
  *         of the previous CRC value.
  * @param  CRCx: pointer to a CRC_TypeDef structure that contains
  *         the configuration information for CRC
  * @param  pBuff: Pointer to the buffer containing the data to be computed
  * @param  u32Len: Length of the buffer to be computed (defined in word, 4 bytes)
  * @retval 16-bit CRC
  */
uint16_t CRC_Calculate_32b(CRC_TypeDef* CRCx, uint32_t* pBuff, uint32_t u32Len)
{
    uint32_t index;

    CRCx->RESULT.RESULT = CRC_RESULT_RESULT;

    /* Enter Data to the CRC calculator */
    for(index = 0; index < u32Len; index++)
    {
        *(volatile uint32_t*)(&CRCx->DATA) = pBuff[index];
    }

    /* Return the CRC computed value */
    return CRCx->RESULT.RESULT;
}

/**
  * @brief  Compute the 32-bit CRC value of an 8, 16 or 32-bit data buffer
  *         starting with the previously computed CRC as initialization value.
  * @param  hcrc CRC handle
  * @param  pBuffer pointer to the input data buffer, exact input data format is
  *         provided .
  * @param  BufferLength input data buffer length (number of bytes if pBuffer
  *         type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
  *         number of words if pBuffer type is * uint32_t).
  * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
  */
uint32_t CRC_Calculate(uint8_t InputType, uint32_t pBuffer[], uint32_t BufferLength)
{
  uint32_t temp = 0;  /* CRC output (read from CRC->DR register) */

  switch (InputType)
  {
    case CRC_InputDataFormat_WORDS:
      /* Enter Data to the CRC calculator */
    temp = CRC_Calculate_32b(CRC, pBuffer, BufferLength);
    break;

    case CRC_InputDataFormat_HALFWORDS:
    temp = CRC_Calculate_16b(CRC, (uint16_t *)(void *)pBuffer, BufferLength);    /* Derogation MisraC2012 R.11.5 */
    break;

    case CRC_InputDataFormat_BYTES:
    temp = CRC_Calculate_8b(CRC, (uint8_t *)pBuffer, BufferLength);
    break;

    default:
    break;
  }

  /* Return the CRC computed value */
  return temp;
}

/**
  * @brief  Get the CRC result flag.
  * @param  CRCx: pointer to a CRC_TypeDef structure that contains
  *         the configuration information for CRC
  * @retval An ErrorStatus enumeration value:
  *          - SUCCESS: CRC result is success.
  *          - ERROR: CRC result is failed.
  */
ErrorStatus CRC_GetResultFlag(CRC_TypeDef* CRCx)
{
    if(CRCx->RESULT.FLAG)
    {
        return SUCCESS;
    }
    else
    {
        return ERROR;
    }
}


/************************ (C) COPYRIGHT CHIPAT *****END OF FILE****/
